﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Matlus.FederatedIdentity;
using System.Xml.Linq;

namespace OAuthClient.oAuth
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        private string realm = null;
        private string provider;
        protected void Page_Load(object sender, EventArgs e)
        {
            realm = Request.Url.Scheme + "://" + Request.Url.DnsSafeHost + ":" + Request.Url.Port + Request.ApplicationPath;

            if (!IsPostBack)
            {
                if (!String.IsNullOrEmpty(Request.PathInfo))
                {
                    if (Request.PathInfo.StartsWith("/requestToken"))
                        MakeRequestForToken();
                    else if (Request.PathInfo.StartsWith("/authorizeToken"))
                        HandleAuthorizeTokenResponse();
                }
            }
        }

        /// <summary>
        /// Step 1: Get a Request Token
        /// </summary>
        private void MakeRequestForToken()
        {
            string consumerKey = null;
            string consumerSecret = null;
            string requestTokenEndpoint = null;
            string requestTokenCallback = null;
            string authorizeTokenUrl = null;

            if (Request.PathInfo == "/requestToken/google/")
            {
                consumerKey = "732818934461.apps.googleusercontent.com";
                consumerSecret = "KHEOJR9TeZ5e-el-P8o5e5CN";
                // Google requires an additional "scope" parameter that identifies one of the google applications
                requestTokenEndpoint = "https://www.google.com/accounts/OAuthGetRequestToken?scope=https://www.googleapis.com/auth/userinfo#email";
                requestTokenCallback = GetRouteableUrlFromRelativeUrl("oAuth/default.aspx/authorizeToken/google/");
                authorizeTokenUrl = "https://www.google.com/accounts/OAuthAuthorizeToken";
            }
            else if (Request.PathInfo == "/requestToken/twitter/")
            {
                consumerKey = "";
                consumerSecret = "";
                requestTokenEndpoint = "https://api.twitter.com/oauth/request_token";
                requestTokenCallback = GetRouteableUrlFromRelativeUrl("oAuth/default.aspx/authorizeToken/twitter/");
                authorizeTokenUrl = "https://api.twitter.com/oauth/authorize";
            }
            else if (Request.PathInfo == "/requestToken/yahoo/")
            {
                consumerKey = "dj0yJmk9S0p2T1pjTTZmMExpJmQ9WVdrOVdXNUdkMnM0TnpZbWNHbzlPRGN6TURJMk5UWXkmcz1jb25zdW1lcnNlY3JldCZ4PTAx";
                consumerSecret = "2124bb5df3133b8cdfe306952d1da8af6678bb1f";
                requestTokenEndpoint = "https://api.login.yahoo.com/oauth/v2/get_request_token";
                requestTokenCallback = GetRouteableUrlFromRelativeUrl("oAuth/default.aspx/authorizeToken/yahoo/");
                authorizeTokenUrl = "https://api.login.yahoo.com/oauth/v2/request_auth";
            }
            else if (Request.PathInfo == "/requestToken/vimeo/")
            {
                consumerKey = "";
                consumerSecret = "";
                requestTokenEndpoint = "http://vimeo.com/oauth/request_token";
                requestTokenCallback = GetRouteableUrlFromRelativeUrl("oAuth/default.aspx/authorizeToken/vimeo/");
                authorizeTokenUrl = "http://vimeo.com/oauth/authorize";
            }

            if (String.IsNullOrEmpty(consumerKey) || String.IsNullOrEmpty(consumerSecret))
                throw new ArgumentException("Please set up your consumer key and consumer secret for the selected provider", "consumerKey or consumerSecret");

            // Step 1: Make the call to request a token
            var oAuthConsumer = new OAuthConsumer();
            var requestToken = oAuthConsumer.GetOAuthRequestToken(requestTokenEndpoint, realm, consumerKey, consumerSecret, requestTokenCallback);
            PersistRequestToken(requestToken);

            // Step 2: Make a the call to authorize the request token
            Response.Redirect(authorizeTokenUrl + "?oauth_token=" + requestToken.Token);
        }

        /// <summary>
        /// Step 3: Exchange the Request Token for an Access Token
        /// </summary>
        private void HandleAuthorizeTokenResponse()
        {
            string consumerKey = null;
            string consumerSecret = null;
            string accessTokenEndpoint = null;
            string token = null;
            string verifier = null;

            if (Request.PathInfo.StartsWith("/authorizeToken/google/"))
            {
                provider = "Google";
                consumerKey = "732818934461.apps.googleusercontent.com";
                consumerSecret = "KHEOJR9TeZ5e-el-P8o5e5CN";
                token = Request.QueryString["oauth_token"];
                verifier = Request.QueryString["oauth_verifier"];
                accessTokenEndpoint = "https://www.google.com/accounts/OAuthGetAccessToken";
            }
            else if (Request.PathInfo.StartsWith("/authorizeToken/twitter/"))
            {
                provider = "Twitter";
                consumerKey = "";
                consumerSecret = "";
                token = Request.QueryString["oauth_token"];
                verifier = Request.QueryString["oauth_verifier"];
                accessTokenEndpoint = "https://api.twitter.com/oauth/access_token";
            }
            else if (Request.PathInfo.StartsWith("/authorizeToken/yahoo"))
            {
                provider = "Yahoo!";
                consumerKey = "dj0yJmk9S0p2T1pjTTZmMExpJmQ9WVdrOVdXNUdkMnM0TnpZbWNHbzlPRGN6TURJMk5UWXkmcz1jb25zdW1lcnNlY3JldCZ4PTAx";
                consumerSecret = "2124bb5df3133b8cdfe306952d1da8af6678bb1f";
                token = Request.QueryString["oauth_token"];
                verifier = Request.QueryString["oauth_verifier"];
                accessTokenEndpoint = "https://api.login.yahoo.com/oauth/v2/get_token";
            }
            else if (Request.PathInfo.StartsWith("/authorizeToken/vimeo/"))
            {
                provider = "Vimeo";
                consumerKey = "";
                consumerSecret = "";
                token = Request.QueryString["oauth_token"];
                verifier = Request.QueryString["oauth_verifier"];
                accessTokenEndpoint = "http://vimeo.com/oauth/access_token";
            }

            if (String.IsNullOrEmpty(consumerKey) || String.IsNullOrEmpty(consumerSecret))
                throw new ArgumentException("Please set up your consumer key and consumer secret for the selected provider", "consumerKey or consumerSecret");

            // Exchange the Request Token for an Access Token
            var oAuthConsumer = new OAuthConsumer();
            var accessToken = oAuthConsumer.GetOAuthAccessToken(accessTokenEndpoint, realm, consumerKey, consumerSecret, token, verifier, GetRequesttoken().TokenSecret);
            // Get email information Google only
            //var responseText = oAuthConsumer.GetUserInfo("https://www.googleapis.com/userinfo/email", realm, consumerKey, consumerSecret, accessToken.Token, accessToken.TokenSecret);
            // Get user profile information Yahoo only
            //string guid = accessToken.AddtionalProperties["xoauth_yahoo_guid"];
            //string url = string.Format("http://social.yahooapis.com/v1/user/{0}/profile/usercard", guid);
            //var responseText = oAuthConsumer.GetUserInfo(url, realm, consumerKey, consumerSecret, accessToken.Token, accessToken.TokenSecret);
            //XElement cachedText = XElement.Parse(responseText);
            //var result = from p in cachedText.Elements("guid") select p;
            //foreach (var item in result)
            //{
            //    var temp = item;
            //}

            //Response.Redirect("~/default.aspx/authenticated/?email=" + responseText.Split('&')[0].Split('=')[1]);
            Response.Redirect("~/default.aspx/authenticated/?email=" + provider);
        }

        void PersistRequestToken(RequestToken requestToken)
        {
            Session["RequestToken"] = requestToken;
        }

        RequestToken GetRequesttoken()
        {
            var requestToken = (RequestToken)Session["RequestToken"];
            Session.Remove("RequestToken");
            return requestToken;
        }

        string GetRouteableUrlFromRelativeUrl(string relativeUrl)
        {
            var url = HttpContext.Current.Request.Url;
            return url.Scheme + "://" + url.Host + ":" + Request.Url.Port + VirtualPathUtility.ToAbsolute("~/" + relativeUrl);
        }
    }
}